<template>
  <div class="main">
    <codemirror class="code" ref="myCm" v-model="code" :options="cmOptions" @changes="onCmCodeChanges" @blur="onCmBlur"
      @keydown.native="onKeyDown" @mousedown.native="onMouseDown" @paste.native="OnPaste">
    </codemirror>
  </div>
</template>
<script>
import sqlFormatter from 'sql-formatter';
import { codemirror } from 'vue-codemirror'
import './setting'

export default {
  props: {
    value: {
      type: String,
      default: () => null
    },
    autoFormat: {
      type: Boolean,
      default: () => false
    },
    lineNumbers: {
      type: Boolean,
      default: () => false
    },
    mode: {
      type: String,
      default: () => 'sql'
    },
    readOnly: {
      type: Boolean,
      default: () => false
    }
  },
  components: {
    codemirror
  },
  watch: {
    value(newValue, oldValue) {
      if (this.autoFormat) {
        this.code = this.codeFormatter(newValue)
      } else {
        this.code = newValue
      }
    }
  },
  data() {
    return {
      code: null,
      cmOptions: {
        tabSize: 4, // tab的空格个数
        indentUnit: 2, //缩进
        autocorrect: true,  // 自动更正
        spellcheck: true,  // 拼写检查
        lint: true,  // 检查格式
        keyMap: 'sublime',
        theme: 'nord', //主题样式
        lineNumbers: this.lineNumbers, //是否显示行数
        lineWrapping: true, //是否自动换行
        styleActiveLine: true, //line选择是是否加亮
        matchBrackets: true, //括号匹配
        mode: this.mode, //实现代码高亮
        readOnly: this.readOnly, //只读
      }
    }
  },
  methods: {
    // 格式化
    codeFormatter(code) {
      if(this.mode === 'sql') {
        return sqlFormatter.format(code)
      } else if(this.mode === 'application/json') {
        if(code instanceof Object) {
          return JSON.stringify(code,null,'\t');//格式化后的json字符串形式
        } 
        return JSON.stringify(JSON.parse(code),null,'\t');//格式化后的json字符串形式
      }
      return code
    },
    // 代码更改时
    onCmCodeChanges(cm, changes) {
      this.$emit("input", cm.getValue());
    },
    // 失去焦点时处理函数
    onCmBlur(cm, event) {
      try {
        let value = cm.getValue();
        if (this.mode === "sql" && value) {
          if (!this.autoFormat) {
            return;
          } 
          this.code = this.codeFormatter(value);
        }
      } catch (e) { }
    },
    // 按下键盘事件处理函数
    onKeyDown(event) {
      const keyCode = event.keyCode || event.which || event.charCode;
      const keyCombination =
        event.ctrlKey || event.altKey || event.metaKey;
      if (!keyCombination && keyCode > 64 && keyCode < 123) {
        this.$refs.myCm.codemirror.showHint({ completeSingle: false });
      }
    },
    // 按下鼠标时事件处理函数
    onMouseDown(event) {
      this.$refs.myCm.codemirror.closeHint();
    },
    // 黏贴事件处理函数
    OnPaste(event) {
      if (this.mode === "sql") {
        try {
          if (!this.autoFormat) {
            return;
          }
          this.code = this.codeFormatter(this.code);
        } catch (e) { }
      }
    },
  },
}
</script>
  
<style scoped>
.main {
  width: calc(100% - 20px);
  height: calc(100% - 10px);
  padding-left: 10px; 
  padding-right: 10px; 
  padding-top: 5px; 
  padding-bottom: 5px; 
  background-color: #2e3440;
}

.code {
  width: 100%;
  height: 100%;
}
</style>
<style>
.CodeMirror {
  height: 100%;
}
/*整个滚动条*/
::-webkit-scrollbar {
    width: 3px;
    height: 0px;
}

/*滑块*/
::-webkit-scrollbar-thumb {
    border-radius: 10px;
    -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.15);
    -moz-osx-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.15);
    background: rgba(0, 0, 0, 0.15);
}

/*滑块的轨道*/
::-webkit-scrollbar-track {
    -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0);
    -moz-osx-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0);
    border-radius: 0;
    background: rgba(0, 0, 0, 0);
}
</style>